package cn.edu.nju.software.cdiy.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;

import cn.edu.nju.software.cdiy.bean.*;
import cn.edu.nju.software.cdiy.dao.*;
import cn.edu.nju.software.cdiy.util.BusinessConstant;

public class OrderHardwareDaoImpl implements OrderHardwareDao {

	@Autowired
	private SessionFactory sessionFactory;
	@Autowired
	private HorderDao horderDaoImpl;
	@Autowired
	private ValueDao valueDao;

	public void setHorderDaoImpl(HorderDao horderDaoImpl) {
		this.horderDaoImpl = horderDaoImpl;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public void setValueDao(ValueDao valueDao) {
		this.valueDao = valueDao;
	}

	@Override
	public OrderHardware save(OrderHardware order_hardware) {
		Session session = sessionFactory.getCurrentSession();
		Transaction tx1 = null;
		OrderHardware ware = null;
		try {
			tx1 = session.beginTransaction();
			session.save(order_hardware);
			tx1.commit();
		} catch (Exception e) {
			if (null != tx1)
				tx1.rollback();
			e.printStackTrace();
		}
		return ware;

	}

	private List<Uorder> loadUorderByDate(GregorianCalendar beginDate,
			GregorianCalendar endDate, Session session) {
		String uordersql = "from Uorder as u where u.time>:startDate and u.time<:endDate and u.state=:state";
		Query query = session.createQuery(uordersql);
		query.setTimestamp("startDate", beginDate.getTime());
		query.setTimestamp("endDate", endDate.getTime());
		System.out.println(beginDate.getTime());
		System.out.println(endDate.getTime());
		query.setParameter("state",
				valueDao.getValue(BusinessConstant.UORDER_STATE1));

		List<Uorder> uorderList = query.list();
		System.out.println(uorderList.size() + "uorderList");
		Iterator<Uorder> uorder = uorderList.iterator();
		while (uorder.hasNext()) {
			System.out.println(uorder.next().getTime());
		}
		return uorderList;
	}

	public List<Uorder> loadUorderByDate2(GregorianCalendar beginDate,
			GregorianCalendar endDate) {
		Session session = sessionFactory.openSession();

		String uordersql = "from Uorder as u where u.time>:startDate and u.time<:endDate";
		Query query = session.createQuery(uordersql);
		query.setTimestamp("startDate", beginDate.getTime());
		query.setTimestamp("endDate", endDate.getTime());

		System.out.println(beginDate.getTime());
		System.out.println(endDate.getTime());

		List<Uorder> uorderList = query.list();
		System.out.println(uorderList.size());
		Iterator<Uorder> uorder = uorderList.iterator();
		while (uorder.hasNext()) {
			System.out.println(uorder.next().getTime());
		}
		return uorderList;
	}

	@Override
	public void uorderToOrderHardware() {
		Session session = sessionFactory.openSession();
		Value chassisValue = valueDao.getValue(BusinessConstant.H_CHASSIS);
		Value cpuValue = valueDao.getValue(BusinessConstant.H_CPU);
		Value diskValue = valueDao.getValue(BusinessConstant.H_DISK);
		Value driverValue = valueDao.getValue(BusinessConstant.H_DRIVER);
		Value graphicsValue = valueDao.getValue(BusinessConstant.H_GRAPHICSA);
		Value mainBoardValue = valueDao.getValue(BusinessConstant.H_MAINBOARD);
		Value memoryValue = valueDao.getValue(BusinessConstant.H_MEMORY);
		Value monitorValue = valueDao.getValue(BusinessConstant.H_MONITOR);
		Value powerValue = valueDao.getValue(BusinessConstant.H_POWER);
		Value radiatorValue = valueDao.getValue(BusinessConstant.H_RADIATOR);
		Value soundboxValue = valueDao.getValue(BusinessConstant.H_SOUNDBOX);
		Value soundcardValue = valueDao.getValue(BusinessConstant.H_SOUNDCARD);
		Value networkAdapterValue = valueDao
				.getValue(BusinessConstant.H_NETWORKADAPER);
		Value state = valueDao.getValue(BusinessConstant.UORDER_STATE2);
		GregorianCalendar registerDate = new GregorianCalendar();
		GregorianCalendar endDate = new GregorianCalendar(
				registerDate.get(Calendar.YEAR),
				registerDate.get(Calendar.MONTH),
				registerDate.get(Calendar.DAY_OF_MONTH),
				registerDate.get(Calendar.HOUR_OF_DAY), 0);
		endDate.add(Calendar.HOUR_OF_DAY, 1);
		GregorianCalendar beginDate = new GregorianCalendar(
				registerDate.get(Calendar.YEAR),
				registerDate.get(Calendar.MONTH),
				registerDate.get(Calendar.DAY_OF_MONTH),
				registerDate.get(Calendar.HOUR_OF_DAY), 0);
		beginDate.add(Calendar.HOUR_OF_DAY, -12);
		Transaction tx1 = null;

		List<Uorder> uorderList;
		// HorderMap 的key是supplier的id
		Map<Integer, Horder> horderMap = new HashMap<Integer, Horder>();

		String supplierSql = "from Supplier";
		List<Supplier> supplierList = session.createQuery(supplierSql).list();

		List<Horder> horderList = new ArrayList<Horder>();
		java.util.Date currentDate = new java.util.Date(
				System.currentTimeMillis());
		Iterator<Supplier> supplierIter = supplierList.iterator();
		Horder horder = null;
		Supplier supplier = null;
		while (supplierIter.hasNext()) {
			horder = new Horder();
			/*
			 * private Long id; private Supplier supplier; private Date time;
			 * private Value state; private Set<OrderHardware> orderHardwares =
			 * new HashSet<OrderHardware>(); private String remark; private
			 * String rsv1; private String rsv2; private String rsv3;
			 */
			supplier = supplierIter.next();
			horder.setSupplier(supplier);
			horder.setTime(currentDate);
			horder.setState(valueDao.getValue(BusinessConstant.HORDER_STATE1));
			horder.setRemark(" ");

			horderMap.put(supplier.getId(), horder);
		}

		try {

			uorderList = loadUorderByDate(beginDate, endDate, session);
			// 找出13类硬件，硬盘和内存有多块需要考虑
			// Chassis，cpu,disk,driver,graphics
			// mainboard,memory,monitor,power,radiator
			// soundbox,soundcard,networkAdapter,

			Iterator<Uorder> uorderIter = uorderList.iterator();
			List<OrderHardware> chassisList = new ArrayList<OrderHardware>();
			List<OrderHardware> cpuList = new ArrayList<OrderHardware>();
			List<OrderHardware> diskList = new ArrayList<OrderHardware>();
			List<OrderHardware> driverList = new ArrayList<OrderHardware>();
			List<OrderHardware> graphicsList = new ArrayList<OrderHardware>();
			List<OrderHardware> mainBoardList = new ArrayList<OrderHardware>();

			List<OrderHardware> memoryList = new ArrayList<OrderHardware>();
			List<OrderHardware> monitorList = new ArrayList<OrderHardware>();
			List<OrderHardware> powerList = new ArrayList<OrderHardware>();
			List<OrderHardware> radiatorList = new ArrayList<OrderHardware>();
			List<OrderHardware> soundBoxList = new ArrayList<OrderHardware>();

			List<OrderHardware> soundCardList = new ArrayList<OrderHardware>();
			List<OrderHardware> networkAdapterList = new ArrayList<OrderHardware>();

			while (uorderIter.hasNext()) {

				Scheme scheme = uorderIter.next().getScheme();
				Chassis chassis = scheme.getChassis();
				if (chassis != null) {
					Iterator<OrderHardware> chassisIter = chassisList
							.iterator();
					boolean check = false;
					while (chassisIter.hasNext()) {
						OrderHardware orderHardware = chassisIter.next();
						if (orderHardware.getHardwareId() == chassis.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						chassisList.add(new OrderHardware((long) chassis
								.getId(), chassis.getModel(), new BigDecimal(
								chassis.getiPrice()), 1, chassisValue, chassis
								.getSupplier()));
				}
				CPU cpu = scheme.getCpu();
				if (cpu != null) {
					Iterator<OrderHardware> cpuIter = cpuList.iterator();
					boolean check = false;
					while (cpuIter.hasNext()) {
						OrderHardware orderHardware = cpuIter.next();
						if (orderHardware.getHardwareId() == cpu.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						cpuList.add(new OrderHardware((long) cpu.getId(), cpu
								.getModel(), new BigDecimal(cpu.getiPrice()),
								1, cpuValue, cpu.getSupplier()));
				}
				Disk disk = scheme.getDisk();
				int disknum = scheme.getDiskNum();
				if (disk != null) {
					Iterator<OrderHardware> diskIter = diskList.iterator();
					boolean check = false;
					while (diskIter.hasNext()) {
						OrderHardware orderHardware = diskIter.next();
						if (orderHardware.getHardwareId() == disk.getId()) {
							orderHardware.incrementByInt(disknum);
							check = true;
							break;
						}
					}
					if (!check)
						diskList.add(new OrderHardware((long) disk.getId(),
								disk.getModel(), new BigDecimal(disk
										.getiPrice()), disknum, diskValue, disk
										.getSupplier()));
				}
				Driver driver = scheme.getDriver();
				if (driver != null) {
					Iterator<OrderHardware> driverIter = driverList.iterator();
					boolean check = false;
					while (driverIter.hasNext()) {
						OrderHardware orderHardware = driverIter.next();
						if (orderHardware.getHardwareId() == driver.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						driverList.add(new OrderHardware((long) driver.getId(),
								driver.getModel(), new BigDecimal(driver
										.getiPrice()), 1, driverValue, driver
										.getSupplier()));
				}
				Graphics graphics = scheme.getGraphics();
				if (graphics != null) {
					Iterator<OrderHardware> graphicsIter = graphicsList
							.iterator();
					boolean check = false;
					while (graphicsIter.hasNext()) {
						OrderHardware orderHardware = graphicsIter.next();
						if (orderHardware.getHardwareId() == graphics.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						graphicsList.add(new OrderHardware((long) graphics
								.getId(), graphics.getModel(), new BigDecimal(
								graphics.getiPrice()), 1, graphicsValue,
								graphics.getSupplier()));
				}
				MainBoard mainBoard = scheme.getMainBoard();
				if (mainBoard != null) {
					Iterator<OrderHardware> mainBoardIter = mainBoardList
							.iterator();
					boolean check = false;
					while (mainBoardIter.hasNext()) {
						OrderHardware orderHardware = mainBoardIter.next();
						if (orderHardware.getHardwareId() == mainBoard.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						mainBoardList.add(new OrderHardware((long) mainBoard
								.getId(), mainBoard.getModel(), new BigDecimal(
								mainBoard.getiPrice()), 1, mainBoardValue,
								mainBoard.getSupplier()));
				}
				Memory memory = scheme.getMemory();
				int memoryNumber = scheme.getMemoryNum();
				if (memory != null) {
					Iterator<OrderHardware> memoryIter = memoryList.iterator();
					boolean check = false;
					while (memoryIter.hasNext()) {
						OrderHardware orderHardware = memoryIter.next();
						if (orderHardware.getHardwareId() == memory.getId()) {
							orderHardware.incrementByInt(memoryNumber);
							check = true;
							break;
						}
					}
					if (!check)
						memoryList.add(new OrderHardware((long) memory.getId(),
								memory.getModel(), new BigDecimal(memory
										.getiPrice()), memoryNumber,
								memoryValue, memory.getSupplier()));
				}
				Monitor monitor = scheme.getMonitor();
				if (monitor != null) {
					if(monitor==null)
						System.out.println("monitor is null");
					Iterator<OrderHardware> monitorIter = monitorList
							.iterator();
					boolean check = false;
					while (monitorIter.hasNext()) {
						OrderHardware orderHardware = monitorIter.next();
						if(monitor==null)
							System.out.println("monitor is null");
							if (orderHardware.getHardwareId() == monitor.getId()) {
								orderHardware.incrementByInt(1);
								check = true;
								break;
							}
						
					}
					if (!check)
						monitorList.add(new OrderHardware((long) monitor
								.getId(), monitor.getModel(), new BigDecimal(
								monitor.getiPrice()), 1, monitorValue, monitor
								.getSupplier()));
				}
				Power power = scheme.getPower();
				if (power != null) {
					Iterator<OrderHardware> powerIter = powerList.iterator();
					boolean check = false;
					while (powerIter.hasNext()) {
						OrderHardware orderHardware = powerIter.next();
						if (orderHardware.getHardwareId() == power.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						powerList.add(new OrderHardware((long) power.getId(),
								power.getModel(), new BigDecimal(power
										.getiPrice()), 1, powerValue, power
										.getSupplier()));
				}
				Radiator radiator = scheme.getRadiator();
				if (radiator != null) {
					Iterator<OrderHardware> radiatorIter = radiatorList
							.iterator();
					boolean check = false;
					while (radiatorIter.hasNext()) {
						OrderHardware orderHardware = radiatorIter.next();
						if (orderHardware.getHardwareId() == radiator.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						radiatorList.add(new OrderHardware((long) radiator
								.getId(), radiator.getModel(), new BigDecimal(
								radiator.getiPrice()), 1, radiatorValue,
								radiator.getSupplier()));
				}
				SoundBox soundBox = scheme.getSoundBox();
				if (soundBox != null) {
					Iterator<OrderHardware> soundBoxIter = soundBoxList
							.iterator();
					boolean check = false;
					while (soundBoxIter.hasNext()) {
						OrderHardware orderHardware = soundBoxIter.next();
						if (orderHardware.getHardwareId() == soundBox.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						soundBoxList.add(new OrderHardware((long) soundBox
								.getId(), soundBox.getModel(), new BigDecimal(
								soundBox.getiPrice()), 1, soundboxValue,
								soundBox.getSupplier()));
				}
				SoundCard soundCard = scheme.getSoundCard();
				if (soundCard != null) {
					Iterator<OrderHardware> soundCardIter = soundCardList
							.iterator();
					boolean check = false;
					while (soundCardIter.hasNext()) {
						OrderHardware orderHardware = soundCardIter.next();
						if (orderHardware.getHardwareId() == soundCard.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						soundCardList.add(new OrderHardware((long) soundCard
								.getId(), soundCard.getModel(), new BigDecimal(
								soundCard.getiPrice()), 1, soundcardValue,
								soundCard.getSupplier()));
				}
				NetworkAdapter networkAdapter = scheme.getNetworkAdapter();
				if (networkAdapter != null) {
					Iterator<OrderHardware> networkAdapterIter = networkAdapterList
							.iterator();
					boolean check = false;
					while (networkAdapterIter.hasNext()) {
						OrderHardware orderHardware = networkAdapterIter.next();
						if (orderHardware.getHardwareId() == networkAdapter.getId()) {
							orderHardware.incrementByInt(1);
							check = true;
							break;
						}
					}
					if (!check)
						networkAdapterList.add(new OrderHardware(
								(long) networkAdapter.getId(), networkAdapter
										.getModel(), new BigDecimal(
										networkAdapter.getiPrice()), 1,
								networkAdapterValue, networkAdapter
										.getSupplier()));
				}
			}
			// while end;
			// save horder;
			System.out.println(chassisList.size());
			System.out.println(cpuList.size());
			System.out.println(diskList.size());
			System.out.println(driverList.size());
			System.out.println(graphicsList.size());

			System.out.println(mainBoardList.size());
			System.out.println(memoryList.size());
			System.out.println(monitorList.size());
			System.out.println(powerList.size());
			System.out.println(radiatorList.size());

			System.out.println(soundBoxList.size());
			System.out.println(soundCardList.size());
			System.out.println(networkAdapterList.size());
			/*
			 * tx1 = session.beginTransaction(); Set<Map.Entry<Integer, Horder>>
			 * entrySet = horderMap.entrySet();
			 * 
			 * Iterator<Map.Entry<Integer, Horder>> iterator =
			 * entrySet.iterator();
			 * 
			 * while (iterator.hasNext()) {
			 * 
			 * Map.Entry<Integer, Horder> entry = iterator.next();
			 * System.out.println(entry.getValue().getOrderHardwares().size());
			 * session.save(entry.getValue());
			 * 
			 * } tx1.commit();
			 */
			addToHorderMap(chassisList, horderMap);
			addToHorderMap(cpuList, horderMap);
			addToHorderMap(diskList, horderMap);
			addToHorderMap(driverList, horderMap);
			addToHorderMap(graphicsList, horderMap);

			addToHorderMap(mainBoardList, horderMap);
			addToHorderMap(memoryList, horderMap);
			addToHorderMap(monitorList, horderMap);
			addToHorderMap(powerList, horderMap);
			addToHorderMap(radiatorList, horderMap);

			addToHorderMap(soundBoxList, horderMap);
			addToHorderMap(soundCardList, horderMap);
			addToHorderMap(networkAdapterList, horderMap);
			tx1 = session.beginTransaction();
			Set<Map.Entry<Integer, Horder>> entrySet = horderMap.entrySet();

			Iterator<Map.Entry<Integer, Horder>> iterator = entrySet.iterator();

			while (iterator.hasNext()) {

				Map.Entry<Integer, Horder> entry = iterator.next();
				System.out.println(entry.getValue().getOrderHardwares().size());
				session.save(entry.getValue());
				System.out.println(entry.getValue().getId());

			}
			Iterator<Uorder> uorderIter2 = uorderList.iterator();
			while (uorderIter2.hasNext()) {
				Uorder uorder2 = uorderIter2.next();
				uorder2.setState(state);
				session.save(uorder2);
			}
			tx1.commit();
		} catch (Exception e) {
			e.printStackTrace();

			tx1.rollback();
		}
		session.close();

	}

	private void addToHorderMap(List<OrderHardware> list,
			Map<Integer, Horder> horderMap) {
		Iterator<OrderHardware> iter = list.iterator();
		while (iter.hasNext()) {
			OrderHardware orderHardware = iter.next();
			System.out.println("supplierid" + orderHardware.getSupplierid());
			Horder horder = horderMap.get(orderHardware.getSupplierid());
			if (horder == null) {
				System.out.println("horder is null");
			}
			horder.getOrderHardwares().add(orderHardware);
		}
	}

	@Override
	public List<OrderHardware> getByHorderId(long horderId, int page,
			int pageSize) {
		Session session = sessionFactory.getCurrentSession();

		List<OrderHardware> returnInt = null;
		try {

			Query query = session
					.createQuery("from OrderHardware o where o.orderId=:id");
			query.setLong("id", horderId);
			query.setFirstResult((page - 1) * pageSize);
			query.setMaxResults(pageSize);
			returnInt = query.list();
		} catch (Exception e) {

			e.printStackTrace();
		}
		return returnInt;
	}

	@Override
	public long getHorderId(long horderId) {
		Session session = sessionFactory.getCurrentSession();

		long returnInt = 0;
		try {

			Query query = session
					.createQuery("select count(*) from OrderHardware o where o.orderId=:id");
			query.setLong("id", horderId);

			returnInt = (Long) query.uniqueResult();
		} catch (Exception e) {

			e.printStackTrace();
		}
		return returnInt;
	}

}
